home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / language / asxsrc.arc / Z80ADR.C < prev    next >
C/C++ Source or Header  |  1989-08-25  |  4KB  |  236 lines

  1. /* z80adr.c */
  2.  
  3. /*
  4.  * (C) Copyright 1989
  5.  * All Rights Reserved
  6.  *
  7.  * Alan R. Baldwin
  8.  * 721 Berkeley St.
  9.  * Kent, Ohio  44240
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <setjmp.h>
  14. #include "asm.h"
  15. #include "z80.h"
  16.  
  17. /*
  18.  * Read an address specifier. Pack the
  19.  * address information into the supplied
  20.  * `expr' structure. Return the mode of
  21.  * the address.
  22.  *
  23.  * This addr(esp) routine performs the following addressing decoding:
  24.  *
  25.  *    address        mode        flag        addr        base
  26.  *    #n        S_IMMED        0        n        NULL
  27.  *    label        s_type        ----        s_addr        s_area
  28.  *    [REG]        S_IND+icode    0        0        NULL
  29.  *    [label]        S_INDM        ----        s_addr        s_area
  30.  *    offset[REG]    S_IND+icode    ----        offset        ----
  31.  */
  32. int
  33. addr(esp)
  34. register struct expr *esp;
  35. {
  36.     register c, mode, indx;
  37.  
  38.     if ((c = getnb()) == '#') {
  39.         expr(esp, 0);
  40.         esp->e_mode = S_IMMED;
  41.     } else
  42.     if (c == LFIND) {
  43.         if (indx=admode(R8)) {
  44.             mode = S_INDB;
  45.         } else
  46.         if (indx=admode(R16)) {
  47.             mode = S_INDR;
  48.         } else    
  49.         if (indx=admode(R8X)) {
  50.             mode = S_R8X;
  51.             aerr();
  52.         } else
  53.         if (indx=admode(R16X)) {
  54.             mode = S_R16X;
  55.             aerr();
  56.         } else {
  57.             expr(esp, 0);
  58.             esp->e_mode = S_INDM;
  59.         }
  60.         if (indx) {
  61.             esp->e_flag = 0;
  62.             esp->e_addr = 0;
  63.             esp->e_mode = mode + indx&0xFF;
  64.             esp->e_base.e_ap = NULL;
  65.         }
  66.         if ((c = getnb()) != RTIND)
  67.             qerr();
  68.     } else {
  69.         unget(c);
  70.         if (indx=admode(R8)) {
  71.             mode = S_R8;
  72.         } else
  73.         if (indx=admode(R16)) {
  74.             mode = S_R16;
  75.         } else    
  76.         if (indx=admode(R8X)) {
  77.             mode = S_R8X;
  78.         } else
  79.         if (indx=admode(R16X)) {
  80.             mode = S_R16X;
  81.         } else {
  82.             expr(esp, 0);
  83.             esp->e_mode = S_USER;
  84.         }
  85.         if (indx) {
  86.             esp->e_flag = 0;
  87.             esp->e_addr = indx&0xFF;
  88.             esp->e_mode = mode;
  89.             esp->e_base.e_ap = NULL;
  90.         }
  91.         if ((c = getnb()) == LFIND) {
  92.             if ((indx=admode(R16))
  93.                 && ((indx&0xFF)==IX || (indx&0xFF)==IY)) {
  94.                 esp->e_mode = S_INDR + (indx&0xFF);
  95.             } else {
  96.                 aerr();
  97.             }
  98.             if ((c = getnb()) != RTIND)
  99.                 qerr();
  100.         } else {
  101.             unget(c);
  102.         }
  103.     }
  104.     return (esp->e_mode);
  105. }
  106.  
  107. /*
  108.  * Enter admode() to search a specific addressing mode table
  109.  * for a match. Return the addressing value on a match or
  110.  * zero for no match.
  111.  */
  112. int
  113. admode(sp)
  114. register struct adsym *sp;
  115. {
  116.     register char *ptr;
  117.     register int i;
  118.     unget(getnb());
  119.     i = 0;
  120.     while ( *(ptr = (char *) &sp[i].a_str) ) {
  121.         if (srch(ptr)) {
  122.             return(sp[i].a_val);
  123.         }
  124.         i++;
  125.     }
  126.     return(0);
  127. }
  128.  
  129. /*
  130.  *      srch --- does string match ?
  131.  */
  132. int
  133. srch(str)
  134. register char *str;
  135. {
  136.     register char *ptr;
  137.     ptr = ip;
  138.  
  139. #if    CASE_SENSITIVE
  140.     while (*ptr && *str) {
  141.         if (*ptr != *str)
  142.             break;
  143.         ptr++;
  144.         str++;
  145.     }
  146.     if (*ptr == *str) {
  147.         ip = ptr;
  148.         return(1);
  149.     }
  150. #else
  151.     while (*ptr && *str) {
  152.         if (ccase[*ptr] != ccase[*str])
  153.             break;
  154.         ptr++;
  155.         str++;
  156.     }
  157.     if (ccase[*ptr] == ccase[*str]) {
  158.         ip = ptr;
  159.         return(1);
  160.     }
  161. #endif
  162.  
  163.     if (!*str)
  164.         if (any(*ptr," \t\n,);")) {
  165.             ip = ptr;
  166.             return(1);
  167.         }
  168.     return(0);
  169. }
  170.  
  171. /*
  172.  *      any --- does str contain c?
  173.  */
  174. int
  175. any(c,str)
  176. char    c, *str;
  177. {
  178.     while (*str)
  179.         if(*str++ == c)
  180.             return(1);
  181.     return(0);
  182. }
  183.  
  184. /*
  185.  * Registers
  186.  */
  187.  
  188. struct    adsym    R8[] = {
  189.     "b",    B|0400,
  190.     "c",    C|0400,
  191.     "d",    D|0400,
  192.     "e",    E|0400,
  193.     "h",    H|0400,
  194.     "l",    L|0400,
  195.     "a",    A|0400,
  196.     "",    0000
  197. };
  198.  
  199. struct    adsym    R8X[] = {
  200.     "i",    I|0400,
  201.     "r",    R|0400,
  202.     "",    0000
  203. };
  204.  
  205. struct    adsym    R16[] = {
  206.     "bc",    BC|0400,
  207.     "de",    DE|0400,
  208.     "hl",    HL|0400,
  209.     "sp",    SP|0400,
  210.     "ix",    IX|0400,
  211.     "iy",    IY|0400,
  212.     "",    0000
  213. };
  214.  
  215. struct    adsym    R16X[] = {
  216.     "af",    AF|0400,
  217.     "af'",    AF|0400,
  218.     "",    0000
  219. };
  220.  
  221. /*
  222.  * Conditional definitions
  223.  */
  224.  
  225. struct    adsym    CND[] = {
  226.     "NZ",    NZ|0400,
  227.     "Z",    Z |0400,
  228.     "NC",    NC|0400,
  229.     "C",    CS|0400,
  230.     "PO",    PO|0400,
  231.     "PE",    PE|0400,
  232.     "P",    P |0400,
  233.     "M",    M |0400,
  234.     "",    0000
  235. };
  236.